package org.yx.service.smfr.create_product_serial;

import java.util.ArrayList;
import java.util.List;

import org.yx.exception.BizException;
import org.yx.models.SbasProdMat;
import org.yx.models.SmfrOrdDef;
import org.yx.models.SmfrOrdOpr;
import org.yx.models.SmfrPsnDtl;
import org.yx.models.SmfrPsnSts;
import org.yx.service.bas.create_rule_code.BasCreateRuleCodeService;
import org.yx.service.smfr.insert_product_serial_history.SmfrInsertProductSerialHistoryIn;
import org.yx.service.smfr.insert_product_serial_history.SmfrInsertProductSerialHistoryService;
import org.yx.utils.BaseService;
import org.yx.utils.FieldMap;
import org.yx.utils.ServiceBeanUtil;

import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;

/**
 * 创建生产产品序列号（条码号）
 * 
 * @author zxw
 * @since 2018/04/22
 **/
public class SmfrCreateProductSerialService extends BaseService {
	private final static String PSN_CODE = "PSN_CODE";

	public SmfrCreateProductSerialOut createProductSerial(SmfrCreateProductSerialIn in) throws Exception {
		String psn = StrUtil.isBlank(in.getPsn()) ? BasCreateRuleCodeService.createRuleCode(PSN_CODE) : in.getPsn();
		if (StrUtil.isBlank(psn)) {
			throw new BizException("SYS-0004", new FieldMap("parameter", "psn"));
		}
		if (StrUtil.isBlank(in.getMo())) {
			throw new BizException("SYS-0004", new FieldMap("parameter", "mo"));
		}
		if (in.getQty() == null || in.getQty().doubleValue() <= 0.00001d) {
			throw new BizException("SYS-0005", new FieldMap("parameter", "qty"), new FieldMap("value", in.getQty()));
		}

		if (selectOne(SmfrPsnSts.class, in.getUserOrgCode(), psn) != null) {
			// psn已经存在，创建失败
			throw new BizException("SMFR-0007", new FieldMap("psn", psn));
		}

		SmfrOrdDef ordDef = selectOne(SmfrOrdDef.class, in.getUserOrgCode(), in.getMo());
		if (ordDef == null || new Character('D').equals(ordDef.getMoStatus())) {
			throw new BizException("SMFR-0004", new FieldMap("mo", in.getMo()));
		}

		SbasProdMat prodMat = selectOne(SbasProdMat.class, ordDef.getOrgCode(), ordDef.getMatCode(), ordDef.getMatVer());
		if (prodMat == null || new Character('D').equals(prodMat.getMatStatus())) {
			throw new BizException("SBAS-0001", new FieldMap("matCode", ordDef.getMatCode()));
		}

		if (new Character('H').equals(prodMat.getMatStatus())) {
			throw new BizException("SQCM-0001", new FieldMap("matCode", ordDef.getMatCode()));
		}

		// 工单不是Open或Process状态时，不能创建条码号
		if (!CollUtil.newArrayList('O', 'P').contains(ordDef.getMoStatus())) {
			throw new BizException("SMFR-0008", new FieldMap("mo", ordDef.getMo()), new FieldMap("moStatus",
					ordDef.getMoStatus()));
		}

		SmfrOrdOpr firstOrdOper = selectOne(SmfrOrdOpr.class, ordDef.getOrgCode(), ordDef.getMo(),
				ordDef.getPathCode(), 1);
		if (firstOrdOper == null) {
			throw new BizException("SMFR-0009", new FieldMap("mo", ordDef.getMo()));
		}

		SmfrPsnSts psnSts = new SmfrPsnSts();
		copyProperties(in, psnSts);
		psnSts.setPsn(psn);
		psnSts.setPathCode(firstOrdOper.getPathCode());
		psnSts.setOper(firstOrdOper.getOper());
		psnSts.setOperSeq(firstOrdOper.getOperSeq());
		psnSts.setMatCode(ordDef.getMatCode());
		psnSts.setMatVer(ordDef.getMatVer());
		psnSts.setDtlSeq(1);
		psnSts.setEventCode("CREATE");
		psnSts.setUnit(prodMat.getUnit());
		psnSts.setCurrentLoc(ordDef.getLineCode());
		psnSts.setPsnType("P");

		insert(psnSts);

		SmfrInsertProductSerialHistoryIn hisIn = new SmfrInsertProductSerialHistoryIn();
		hisIn.setPsnSts(psnSts);
		ServiceBeanUtil.getBean(SmfrInsertProductSerialHistoryService.class).insertProductSerialHistory(hisIn);

		Double inQty = ordDef.getInQty();
		if (in.getQty() != null) {
			inQty = NumberUtil.add(inQty, in.getQty());
		}

		// 父批次下绑定有多个子批次，子批次处理数据同父批次
		if (CollUtil.isNotEmpty(in.getChildPsnList())) {
			List<SmfrPsnSts> children = new ArrayList<SmfrPsnSts>();
			for (SmfrPsnSts childPsn : in.getChildPsnList()) {
				if (StrUtil.isBlank(childPsn.getPsn())) {
					throw new BizException("SYS-0005", FieldMap.of("parameter", "childPsnList.psn"), FieldMap.of(
							"value", childPsn.getPsn()));
				}

				if (selectOne(SmfrPsnSts.class, psnSts.getOrgCode(), childPsn.getPsn()) != null) {
					throw new BizException("SMFR-0007", "条码号${psn}已经存在。", FieldMap.of("psn", childPsn.getPsn()));
				}

				SmfrPsnSts cpsn = ObjectUtil.clone(childPsn);
				copyProperties(psnSts, cpsn);
				cpsn.setPsnType("C");
				cpsn.setQty(childPsn.getQty());
				cpsn.setCarryId(psnSts.getPsn());
				children.add(cpsn);

				if (in.getQty() == null) {
					inQty = NumberUtil.add(inQty, cpsn.getQty());
				}
			}

			insertBatch(children);

			hisIn.setPsnSts(null);
			hisIn.setPsnStsList(children);
			ServiceBeanUtil.getBean(SmfrInsertProductSerialHistoryService.class).insertProductSerialHistory(hisIn);
		}

		SmfrPsnDtl psnDtl = new SmfrPsnDtl();
		copyProperties(psnSts, psnDtl);
		psnDtl.setSeqNum(psnSts.getDtlSeq());

		insert(psnDtl);

		ordDef.setInQty(inQty);
		update(ordDef, "inQty");

		if (ordDef.getActualStartTime() == null) {
			ordDef.setActualStartTime(getCurrentTime());

			update(ordDef, "actualStartTime");
		}

		if (!new Character('P').equals(ordDef.getMoStatus())) {
			ordDef.setMoStatus('P');

			update(ordDef, "moStatus");
		}

		SmfrCreateProductSerialOut out = new SmfrCreateProductSerialOut();
		out.setPsn(psn);

		return out;
	}
}